package com.sneakxy.cloudbase.platform.controller;

import java.util.ArrayList;
import java.util.List;

import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import com.sneakxy.cloudbase.platform.bean.Role;
import com.sneakxy.cloudbase.platform.bean.RolePerm;
import com.sneakxy.cloudbase.platform.bean.ValidAdd;
import com.sneakxy.cloudbase.platform.bean.ValidEdit;
import com.sneakxy.cloudbase.platform.bean.dto.PermissionDTO;
import com.sneakxy.cloudbase.platform.bean.dto.RoleDTO;
import com.sneakxy.cloudbase.platform.bean.dto.RoleTreeDTO;
import com.sneakxy.cloudbase.platform.service.IAccountRoleService;
import com.sneakxy.cloudbase.platform.service.IPermissionService;
import com.sneakxy.cloudbase.platform.service.IRolePermService;
import com.sneakxy.cloudbase.platform.service.IRoleService;
import com.sneakxy.cloudbase.platform.utils.web.BeanHelper;
import com.sneakxy.cloudbase.platform.utils.web.DataGrid;
import com.sneakxy.cloudbase.platform.utils.web.PageSearch;
import com.sneakxy.cloudbase.platform.utils.web.Response;
import com.sneakxy.cloudbase.platform.utils.web.signature.RequireSignature;

import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import springfox.documentation.annotations.ApiIgnore;

@Api(tags="角色服务接口")
@RestController
@RequestMapping("/api/role/")
public class RoleController {

	@Autowired
	private IRoleService roleService;
	
	@Autowired
	private IPermissionService permissionService;
	
	@Autowired
	private IRolePermService rolePermService;
	
	@Autowired
	private IAccountRoleService accountRoleService;
	
	@ApiOperation("角色分页查询")
	@RequireSignature
	@RequiresPermissions("sys:role:manager")
	@PostMapping("datagrid")
	public Response<DataGrid<RoleDTO>> datagrid(PageSearch<String> search) {
		if(StringUtils.isBlank(search.getSortName())) {
			search.setSortName("createtime");
		}
		Page<Role> page = roleService.findBySearch(search.getSearch(), search.toPageable());
		return Response.ok(DataGrid.newInstance(page, RoleDTO::from));
	}
	
	@ApiImplicitParams({
		@ApiImplicitParam(name="id", value="角色ID", dataType="String", dataTypeClass = String.class, paramType="query", required=true),
		@ApiImplicitParam(name="name", value="角色名称", dataType="String", dataTypeClass = String.class, paramType="query", required=true),
		@ApiImplicitParam(name="memo", value="备注", dataType="String", dataTypeClass = String.class, paramType="query", required=false)
	})
	@ApiOperation("添加角色")
	@RequireSignature
	@RequiresPermissions("sys:role:manager:add")
	@PostMapping("add")
	public Response<RoleDTO> add(
			@Validated(ValidAdd.class)
			@ApiIgnore 
			RoleDTO dto) {
		if(!validate(dto.getId()).getData()) {
			return Response.fail(1);
		}
		//去空格
		BeanHelper.trimToEmpty(dto);
		
		Role role = RoleDTO.to(dto);
		role.setNew(true);
		role.setSort(0);
		role = roleService.save(role);
		
		return Response.ok(RoleDTO.from(role));
	}
	
	@ApiOperation("添加角色校验")
	@RequireSignature
	@RequiresPermissions("sys:role:manager:add")
	@PostMapping("validate")
	public Response<Boolean> validate(
			@ApiParam(name="id", value="角色ID", required = true)
			@RequestParam(name="id")
			String id) {
		return Response.ok(!roleService.exists(id));
	}
	
	@ApiImplicitParams({
		@ApiImplicitParam(name="id", value="角色ID", dataType="String", dataTypeClass = String.class, paramType="query", required=true),
		@ApiImplicitParam(name="name", value="角色名称", dataType="String", dataTypeClass = String.class, paramType="query", required=true),
		@ApiImplicitParam(name="memo", value="备注", dataType="String", dataTypeClass = String.class, paramType="query", required=false)
	})
	@ApiOperation("角色编辑")
	@RequireSignature
	@RequiresPermissions("sys:role:manager:edit")
	@PostMapping("edit")
	public Response<RoleDTO> edit(
			@Validated(ValidEdit.class)
			@ApiIgnore 
			RoleDTO dto) {
		//去空格
		BeanHelper.trimToEmpty(dto);
		
		Role role = RoleDTO.to(dto);
		role.setNew(false);
		role.setSort(null);
		role.setCreatetime(null);
		role = roleService.save(role);
		
		return Response.ok(RoleDTO.from(role));
	}
	
	@ApiOperation("角色删除")
	@RequireSignature
	@RequiresPermissions("sys:role:manager:remove")
	@PostMapping("remove")
	public Response<String> remove(
			@ApiParam(name="ids", value="角色ID集合", required = true)
			@RequestParam(name="ids")
			String[] ids) {
		if(ids != null) {
			for(String id:ids) {
				roleService.removeCascad(id);
			}
		}
		return Response.ok();
	}
	
	@ApiOperation("角色树信息")
	@RequireSignature
	@RequiresPermissions("sys:role:manager:perm")
	@PostMapping("tree")
	public Response<RoleTreeDTO> tree(
			@ApiParam(name="id", value="角色ID", required = true)
			@RequestParam(name="id")
			String id) {
		RoleTreeDTO result = new RoleTreeDTO();
		List<PermissionDTO> list = permissionService.findAllByParentId(true);
		result.setId("root");
		result.setI18n("sys.role.manager.perm");
		result.setOpen(true);
		result.setNocheck(true);
		result.setChildren(list);
		List<String> perms = rolePermService.findPermissions(id);
		result.setPerms(perms);
		return Response.ok(result);
	}
	
	@ApiOperation("角色赋权")
	@RequireSignature
	@RequiresPermissions("sys:role:manager:perm")
	@PostMapping("perm")
	public Response<String> perm(
			@ApiParam(name="id", value="角色ID", required = true)
			@RequestParam(name="id")
			String id, 
			@ApiParam(name="permIds", value="权限ID集合")
			@RequestParam(name="permIds", required = false)
			String[] permIds) {
		String roleId = StringUtils.trimToEmpty(id);
		Role role = roleService.findOne(roleId);
		//删除已经分配权限
		rolePermService.deleteByRoleId(roleId);
		if(role != null) {
			//重新分配权限
			if(permIds != null) {
				List<RolePerm> rps = new ArrayList<>();
				for(String permId : permIds) {
					rps.add(new RolePerm(roleId, permId));
				}
				rolePermService.save(rps);
			}
			return Response.ok();
		}
		return Response.fail();
	}
	
	@ApiOperation("查询单个角色信息")
	@RequireSignature
	@PostMapping("one")
	public Response<RoleDTO> one(
			@ApiParam(name="id", value="角色ID", required = true)
			@RequestParam(name="id", required = true)
			String id) {
		Role role = roleService.findOne(id);
		return Response.ok(role, RoleDTO::from);
	}
	
	@ApiOperation("查询多个角色ID")
	@RequireSignature
	@PostMapping("roles")
	public Response<List<String>> roles(
			@ApiParam(name="accountId", value="账户ID", required = true)
			@RequestParam(name="accountId")
			String accountId) {
		List<String> result = accountRoleService.findRoles(accountId);
		return Response.ok(result);
	}
	
}
